<?php


namespace app\unify\controller;


use app\BaseController;
use app\unify\model\Role as RoleModel;
use think\annotation\route\Validate;
use think\db\Query;
use think\facade\Db;
use think\Request;
use app\unify\validate\Role as RoleValidate;
use app\unify\model\RoleAuth as RoleAuthModel;
use app\unify\model\Auth as AuthModel;


class Role extends BaseController
{
    /**
     * 角色列表
     *
     * @return \think\Paginator
     * @throws \think\db\exception\DbException
     */
    public function index(Request $r)
    {
        $where = [];

        $authIds = $r->param('authIds/a');
        if ($authIds) {
            $where[] = ['id', 'in', RoleAuthModel::where([
                ['auth_id', 'in', $authIds]
            ])->column("role_id")];
        }

        $keywords = $r->param('keywords');
        if ($keywords) {
            $where[] = ['name|description', 'LIKE', "%{$keywords}%"];
        }

        $name = $r->param('name');
        if ($name) {
            $where[] = ['name', 'LIKE', "%{$name}%"];
        }

        $description = $r->param('description');
        if ($description) {
            $where[] = ['description', 'LIKE', "%{$description}%"];
        }

        return RoleModel::where($where)->with(['auths'])->order("id DESC")->paginate($this->limit)->each(function (&$item) {
            $authsNameList = [];
            foreach ($item['auths'] as $auth) {
                $authsNameList[] = $auth['name'];
            }
            $item['authsName'] = implode("、", $authsNameList);
            unset($item['auths']);
        });

    }


    /**
     * 角色表单
     *
     * @param mixed $id
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function form(mixed $id = 0): array
    {
        $authList = AuthModel::select()->toArray();
        $data = [
            'entity' => new \stdClass(),
            'authIds' => $authList
        ];

        if ($id) {
            $entity = RoleModel::find($id);
            $entity['authList'] = $entity->auths->map(fn($item) => strval($item->pivot->auth_id));
            $data['entity'] = $entity;
        }

        return $data;
    }

    /**
     * 新增角色
     *
     * @param \think\Request $request
     * @return string
     */
    #[Validate(RoleValidate::class, scene: RoleValidate::SAVE)]
    public function save(Request $request, RoleModel $roleModel): string
    {
        $params = $request->param();

        Db::transaction(function () use ($roleModel, $params) {

            $params['creator_id'] = \app\unify\model\User::id();

            $role = RoleModel::create($params);


            //新增数据
            $role->auths()->saveAll($params['authList']);

        });


        return '操作成功';
    }

    /**
     * 角色信息
     *
     * @param int $id
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function read($id)
    {
        return RoleModel::findOrEmpty($id)->toArray();
    }


    /**
     * 修改角色
     *
     * @param \think\Request $request
     * @param int $id
     * @return string
     */
    #[Validate(RoleValidate::class, scene: RoleValidate::UPDATE)]
    public function update(Request $request, int $id): string
    {
        $params = $request->param();

        Db::transaction(function () use ($id, $params) {

            $role = RoleModel::findOrEmpty($id);
            if (!$role) {
                throw new \Exception('角色不存在');
            }

            $role->save($params);

            //删除原有的
            $role->auths()->detach();

            //新增数据
            $role->auths()->saveAll($params['authList']);

        });

        return '操作成功';
    }

    /**
     * 删除角色
     *
     * @param array $ids
     * @return string
     */
    #[Validate(RoleValidate::class, scene: RoleValidate::DELETE)]
    public function delete(array $ids): string
    {
        RoleModel::destroy(function (Query $q) use ($ids) {
            $q->where(RoleModel::getPrimaryKey(), 'in', $ids);
        });

        return '删除成功';
    }
}